/*********************************************************************************
 * Software License Agreement (BSD License)
 * Copyright (c) 2012, Carlos D. Correa (info@ngraph.org)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of netzen nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************************/
#include <QHBoxLayout>
#include <QAction>
#include <QMenuBar>
#include <QStatusBar>
#include <QFileDialog>
#include <QCoreApplication>
#include <QErrorMessage>
#include <QMessageBox>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolBox>
#include "borderlayout.h"
#include "qNWindow.h"
#include "qNRender.h"
#include "tabbar.h"
#include "qShortcutBar.h"
//#include "../views/tableView.h" //0615

#include <assert.h>

QNWindow::QNWindow(Controller *controller) {
    this->controller = controller;
    assert(controller);

    //QHBoxLayout *layout = new QHBoxLayout();
    BorderLayout *layout = new BorderLayout();

	QWidget *upperBar = new QWidget(this);
    QVBoxLayout *vboxLayout = new QVBoxLayout();
	
	//QToolBox *toolbox = new QToolBox(this);
	QShortcutBar *shortcutBar = new QShortcutBar(controller,this);
	vboxLayout->addWidget(shortcutBar);

	//QDockWidget *searchDock = new QDockWidget("Search");
	/*
    QWidget *box = new QWidget(this);
    QHBoxLayout *boxLayout = new QHBoxLayout(this);
    boxLayout->addWidget(new QLabel("Search :  ", box));
	search = new QLineEdit();
    connect(search, SIGNAL(returnPressed()),this, SLOT(doSearch()));
    boxLayout->addWidget(search);
	box->setLayout(boxLayout);
  */
	//vboxLayout->addWidget(box);
	//searchDock->setWidget(box);
	//vboxLayout->addWidget(searchDock);
	//toolbox->insertItem(0, shortcutBar, "shortcuts");
	//toolbox->insertItem(1, box, "search");
	upperBar->setLayout(vboxLayout);


    QNRender *render = new QNRender(controller,this);
    render->setMinimumWidth(640);
    render->setMinimumHeight(480);

    Tabbar *tabbar = new Tabbar(controller,this);
    tabbar->setMinimumWidth(400); //0615: original value 400

    QStatusBar *statusBar = new QStatusBar(this);
    statusBar->showMessage(tr("NetZen v1.0"));
	
	

//    string strTableTestName = "test"; //0615
//    myTableView *mytb = new myTableView(strTableTestName.c_str(),this);
//    mytb->setMinimumWidth(200);
//    ((Clickable *)mytb)->setLocation(0.0, 0.0);
//    ((Clickable *)mytb)->setSize(0.9, 0.9);
//    ((Clickable *)mytb)->setVisible(true);
//    ((View *)mytb)->addCloseButton();
//    ((View *)mytb)->addTransparentButton();
//    layout->addWidget(mytb,BorderLayout::West);


    layout->addWidget(upperBar, BorderLayout::North);
	//layout->addWidget(toolbox, BorderLayout::North);
    layout->addWidget(render, BorderLayout::Center);
    layout->addWidget(tabbar, BorderLayout::East);
    layout->addWidget(statusBar, BorderLayout::South);
    setLayout(layout);
    setWindowTitle("NetZen v1.0");
    createMenu();
}

void QNWindow::doSearch() {
    string searchStr = search->text().toStdString();
    printf("Searching [%s]\n", searchStr.c_str());
    controller->doSearch(searchStr);
    controller->updateRender();
}

void QNWindow::createMenu() {
    QAction *loadWorkspace = new QAction(tr("&Load Workspace..."), this);
    loadWorkspace->setShortcut(tr("Ctrl+L"));
    loadWorkspace->setStatusTip(tr("LoadWorkspace an existing script"));
    connect(loadWorkspace, SIGNAL(triggered()), this, SLOT(loadWorkspace()));

    QAction *saveWorkspace = new QAction(tr("&Save Workspace..."), this);
    saveWorkspace->setShortcut(tr("Ctrl+S"));
    saveWorkspace->setStatusTip(tr("Save current workspace"));
    connect(saveWorkspace, SIGNAL(triggered()), this, SLOT(saveWorkspace()));

    QAction *open = new QAction(tr("&Open script..."), this);
    open->setShortcut(tr("Ctrl+O"));
    open->setStatusTip(tr("Open an existing script"));
    connect(open, SIGNAL(triggered()), this, SLOT(open()));

    QAction *import = new QAction(tr("&Import Table..."), this);
    import->setShortcut(tr("Ctrl+I"));
    import->setStatusTip(tr("Import Node Table"));
    connect(import, SIGNAL(triggered()), this, SLOT(importTable()));

    QAction *importEdge = new QAction(tr("Import &Edge Table..."), this);
    importEdge->setShortcut(tr("Ctrl+E"));
    importEdge->setStatusTip(tr("Import Edge Table"));
    connect(importEdge, SIGNAL(triggered()), this, SLOT(importEdgeTable()));

    QAction *about = new QAction(tr("about"), this);
    about->setShortcut(tr("Ctrl+A"));
    about->setStatusTip(tr("About NetZen"));
    connect(about, SIGNAL(triggered()), this, SLOT(about()));

    QAction *quit = new QAction(tr("Quit"), this);
    quit->setShortcut(tr("Ctrl+A"));
    quit->setStatusTip(tr("Quit NetZen"));
    connect(quit, SIGNAL(triggered()), this, SLOT(quit()));


    QMenuBar *menubar = new QMenuBar(this);
    QMenu *fileMenu = menubar->addMenu(tr("&File"));
    fileMenu->addAction(import);
    fileMenu->addAction(importEdge);
    fileMenu->addSeparator();

    fileMenu->addAction(loadWorkspace);
    fileMenu->addAction(saveWorkspace);
    fileMenu->addSeparator();
    fileMenu->addAction(open);
    fileMenu->addSeparator();

    fileMenu->addAction(quit);

    QMenu *viewMenu = menubar->addMenu(tr("&View"));
    QMenu *createView = viewMenu->addMenu(tr("&Create"));
    vector<string> viewCreators = controller->getViewCreators();
    for(unsigned int i=0;i<viewCreators.size();i++) {
        string type = viewCreators[i];
        QAction *create = new QAction(tr(type.c_str()), this);
        connect(create, SIGNAL(triggered()), this, SLOT(createView()));
        createView->addAction(create);
    }

    QMenu *layoutMenu = menubar->addMenu(tr("&Layout"));
    QMenu *createLayout = layoutMenu->addMenu(tr("&Create"));
    vector<string> layoutCreators = controller->getLayoutCreators();
    for(unsigned int i=0;i<layoutCreators.size();i++) {
        string type = layoutCreators[i];
        QAction *create = new QAction(tr(type.c_str()), this);
        connect(create, SIGNAL(triggered()), this, SLOT(createLayout()));
        createLayout->addAction(create);
    }


    QMenu *help = menubar->addMenu(tr("&Help"));
    help->addAction(about);

    BorderLayout *mylayout = static_cast<BorderLayout*> (layout());
    mylayout->addWidget(menubar, BorderLayout::North);
}

void QNWindow::createView() {
    assert(controller);
    QAction *menu = static_cast<QAction*>(sender());
    assert(menu);
    string type = menu->text().toStdString();
    printf("[QNWindow] Create view of type %s\n", type.c_str());
    controller->createView(type, type);
}

void QNWindow::createLayout() {
    assert(controller);
    QAction *menu = static_cast<QAction*>(sender());
    assert(menu);
    string type = menu->text().toStdString();
    printf("[QNWindow] Create layout of type %s\n", type.c_str());
    controller->createLayout(type, type);
}

void QNWindow::quit() {
    QCoreApplication::quit();
}

void QNWindow::about() {
    //QMessageBox ::about(this, "NetZen v0.1", "Created by Carlos D. Correa\n\nContributors\nCarlos D. Correa\nTarik Crnovrsanin\n\n2009");

    QMessageBox msgBox(this);
    msgBox.setIconPixmap(QPixmap("netzen.png"));
    msgBox.setText("NetZen v0.1");
    msgBox.setInformativeText("http://vis.cs.ucdavis.edu/~correac/netzen\nCreated by Carlos D. Correa\n\nContributors\nCarlos D. Correa\nTarik Crnovrsanin\n\n2009");
    msgBox.exec();

}

void QNWindow::open() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Open script"), "", tr("Script files (*.script);;All files (*.*)"));
    if(!filename.isNull()) {
        string name = filename.toStdString();
        controller->readScript(name.c_str());
    }
}

void QNWindow::importTable() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Import Table"), "", tr("Tab separated files (*.txt);;All Files(*.*)"));

    if(!filename.isNull()) {
        string name = filename.toStdString();
        controller->importTable((controller->getGraph("graph")), name.c_str());
    }

}

void QNWindow::importEdgeTable() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Import Edge Table"), "", tr("Tab separated files (*.txt);;All files(*.*)"));

    if(!filename.isNull()) {
        string name = filename.toStdString();
        controller->importEdgeTable((controller->getGraph("graph")), name.c_str());
    }
}

void QNWindow::loadWorkspace() {
    QString filename = QFileDialog::getOpenFileName(this, tr("Load Workspace"), "", tr("Workspace files (*.ws);;All files(*.*)"));

    if(!filename.isNull()) {
        string name = filename.toStdString();
        printf("Attempting to open %s\n", name.c_str());
        bool res = controller->loadWorkspace(name.c_str());
        if(!res) {
            QMessageBox::critical(this, "Loading Workspace", "The selected file cannot be opened");
            //QErrorMessage error(this);
            //error.showMessage("The selected file cannot be opened");
        }
    }
}
void QNWindow::saveWorkspace() {
    QString filename = QFileDialog::getSaveFileName(this, tr("Save Workspace"), "", tr("Workspace files (*.ws *.*"));

    if(!filename.isNull()) {
        string name = filename.toStdString();
        controller->saveWorkspace(name.c_str());
    }
}

